package com.lzw.breezeNovel.webApp.service.impl.user;

import com.lzw.breezeNovel.common.exception.BaseException;
import com.lzw.breezeNovel.common.login.LoginUser;
import com.lzw.breezeNovel.common.login.LoginUserHolder;
import com.lzw.breezeNovel.common.result.ResultCodeEnum;
import com.lzw.breezeNovel.model.entity.pojo.user.UserAtten;
import com.lzw.breezeNovel.model.entity.pojo.user.UserInfo;
import com.lzw.breezeNovel.model.entity.query.PaginationResultQuery;
import com.lzw.breezeNovel.webApp.mapper.user.UserAttenMapper;
import com.lzw.breezeNovel.webApp.mapper.user.UserInfoMapper;
import com.lzw.breezeNovel.webApp.service.user.UserAttenService;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * @author 清风明月
 * @Package com.lzw.breezeNovel.webApp.service.impl.user
 * @date 2025/3/25
 * @description 用户关注表
 */
@Service
@SuppressWarnings("all")
public class UserAttenServiceImpl implements UserAttenService {

    /**
     * 注入mapper
     */
    @Autowired
    private UserAttenMapper userAttenMapper;
    /**
     * 注入用户mapper
     */
    @Autowired
    private UserInfoMapper userInfoMapper;

    /**
     * 添加关注
     * @param userId
     * @param ortherId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(Long userId, Long ortherId) {
        //判断是否已经关注
        Boolean isAtten = userAttenMapper.selectByUserIdAndOrtherId(userId,ortherId) > 0;
        if(isAtten){
            throw new BaseException(400,"已经关注过了");
        }
        //创建实体对象
        UserAtten userAtten = new UserAtten();
        userAtten.setUserId(userId);
        userAtten.setOrtherId(ortherId);
        //关注的时间
        userAtten.setCreateTime(new Date());
        //对更新被关在的用户的粉丝量
        userInfoMapper.updateFanAdd(ortherId);
        //更新关注用户的关注量
        userInfoMapper.updateAttention(userId);
        //添加关注
        userAttenMapper.insert(userAtten);
    }

    /**
     * 取消关注
     * @param userId
     * @param ortherId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void del(Long userId, Long ortherId) {
        //判断是否已经关注
        Boolean isAtten = userAttenMapper.selectByUserIdAndOrtherId(userId,ortherId) > 0;
        if(!isAtten){
            throw new BaseException(400,"你并没有关注过这个用户");
        }
        //获取被关住的用户信息
        userInfoMapper.updateFanSub(ortherId);
        //更新关注用户的关注量
        userInfoMapper.updateAttentionSub(userId);
        //取消关注
        userAttenMapper.delByuserIdAndOrtherId(userId,ortherId);
    }

    /**
     * 分页查询关注列表
     * @param pageNo
     * @param size
     * @return
     */
    @Override
    public PaginationResultQuery<UserAtten> list(Integer pageNo, Integer size) {
        //获取当前用户
        Long userId = getUserId();
        //计算分页
        Integer start = startPage(pageNo, size);
        //分页查询数据
        List<UserAtten> userAttenList = userAttenMapper.selectByUserId(userId, start, size);
        //分装分页对象
        PaginationResultQuery<UserAtten> paginationResultQuery = new PaginationResultQuery<>(0,start,size,userAttenList);
        return paginationResultQuery;
    }

    /**
     * 计算分页
     * @param pageNo
     * @param size
     * @return
     */
    @Nullable
    @Contract(pure = true)
    private Integer startPage(Integer pageNo, Integer size) {
        pageNo = Optional.ofNullable(pageNo).orElse(1);
        size = Optional.ofNullable(size).orElse(10);
        pageNo = Math.max(pageNo, 1);
        size = Math.max(size, 1);
        return (pageNo - 1) * size;
    }

    /**
     * 获取当前用户
     * @return
     */
    @Nullable
    @Contract(pure = true)
    private Long getUserId() {
        LoginUser loginUser = LoginUserHolder.getLoginUser();
        if(loginUser == null){
            throw new BaseException(ResultCodeEnum.APP_LOGIN_AUTH);
        }
        //获取手机号
        String phone = loginUser.getPhone();
        //查询用户信息
        UserInfo userInfo = userInfoMapper.selectByPhone(phone);
       return userInfo.getUserId();
    }
}
